import { Point, Point3, Rect } from '@/types';
import { groupBy } from 'lodash-es';
import moment from 'moment';
import { Points, Shape, Vector2 } from 'three';

interface Point3Obj {
  x: number;
  y: number;
  z: number;
}

type Point3Arr = [number, number, number];

export function xyz(p: Point3Obj): Point3Arr {
  return [p.x, p.y, p.z];
}

export function dateFormat(date: number): string {
  return moment(date).format('YYYY-MM-DD HH:mm:ss');
}

export function getRoundedRectShape(
  shape: Shape,
  x: number,
  y: number,
  width: number,
  height: number,
  radius: number,
) {
  shape.moveTo(x, y + radius);
  shape.lineTo(x, y + height - radius);
  shape.quadraticCurveTo(x, y + height, x + radius, y + height);
  shape.lineTo(x + width - radius, y + height);
  shape.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
  shape.lineTo(x + width, y + radius);
  shape.quadraticCurveTo(x + width, y, x + width - radius, y);
  shape.lineTo(x + radius, y);
  shape.quadraticCurveTo(x, y, x, y + radius);

  return shape;
}

/** 获取指定向量的垂直向量 */
export function getPerpVector(vec: Vector2) {
  const { x, y } = vec;
  const perp = new Vector2(-y, x);
  perp.normalize();
  return perp;
}

export function offsetPoint<T extends number[]>(point: T, offset: number[]) {
  return point.map((num, i) => {
    const offsetNum = offset[i];
    if (!offsetNum) return num;
    return num + offsetNum;
  }) as T;
}

export function navigatePoint<T extends number[]>(point: T) {
  return point.map((num) => {
    return -num;
  }) as T;
}

export function getMiddlePoint<T extends number[]>(start: T, end: T): T {
  const middlePoint: number[] = [];
  for (let i = 0; i < start.length; i++) {
    const startNum = start[i];
    const endNum = end[i];
    const middleNum = (startNum + endNum) / 2;
    middlePoint.push(middleNum);
  }
  return middlePoint as T;
}

export function point2point3(point: Point, z?: number): Point3 {
  return [...point, z ?? 0];
}

export function point3point2(point: Point3): Point {
  const newPoint = [...point];
  newPoint.pop();
  return newPoint as Point;
}

type Quadrant = 1 | 2 | 3 | 4;
export function getPointQuadrant(point: Point): Quadrant {
  const [x, y] = point;
  if (x > 0 && y > 0) {
    return 1;
  } else if (x < 0 && y > 0) {
    return 2;
  } else if (x < 0 && y < 0) {
    return 3;
  } else {
    return 4;
  }
}

export function groupPointsByQuadrant(points: Point[]) {
  return groupBy(points, getPointQuadrant);
}
